/**
 * @author Vitor Franco do Carmo (vfcarmo@gmail.com)
 * @since 30/10/2013
 *
 */
package br.com.vfcfw.persistence.interceptor;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLClientInfoException;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.CallbackException;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;

/**
 * @author Vitor Franco do Carmo (vfcarmo@gmail.com)
 * @since 30/10/2013
 * 
 */
public class HibernateInterceptor extends EmptyInterceptor {

    /** */
    private static final long serialVersionUID = 4032117604420577620L;

    @PersistenceContext
    private EntityManager entityManager;

    /**
     * {@inheritDoc}
     * 
     * @see org.hibernate.EmptyInterceptor#onCollectionRemove(java.lang.Object, java.io.Serializable)
     */
    @Override
    public void onCollectionRemove(Object collection, Serializable key) throws CallbackException {

        adicionarClientInfo("Eu");
        super.onCollectionRemove(collection, key);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.hibernate.EmptyInterceptor#onCollectionUpdate(java.lang.Object, java.io.Serializable)
     */
    @Override
    public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException {

        adicionarClientInfo("Eu");
        super.onCollectionUpdate(collection, key);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.hibernate.EmptyInterceptor#onDelete(java.lang.Object, java.io.Serializable, java.lang.Object[],
     *      java.lang.String[], org.hibernate.type.Type[])
     */
    @Override
    public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {

        adicionarClientInfo("Eu");
        super.onDelete(entity, id, state, propertyNames, types);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.hibernate.EmptyInterceptor#onSave(java.lang.Object, java.io.Serializable, java.lang.Object[],
     *      java.lang.String[], org.hibernate.type.Type[])
     */
    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {

        adicionarClientInfo("Eu");
        return super.onSave(entity, id, state, propertyNames, types);
    }

    /**
     * Adiciona uma informação na conexão.
     * 
     * @param usuarioAutenticado Usuário autenticado.
     */
    private void adicionarClientInfo(String usuarioAutenticado) {

        try {

            obterConexao().setClientInfo("User", usuarioAutenticado);
        } catch (SQLClientInfoException e) {
            e.printStackTrace();
        }
    }

    /**
     * Retorna a conexão com o banco de dados.
     * 
     * @return {@link Connection}.
     */
    private Connection obterConexao() {

        return entityManager.unwrap(Connection.class);
    }
}
